#!/bin/bash

# Java进程内存监控和自动重启脚本
# 作者：系统管理员
# 创建时间：$(date '+%Y-%m-%d %H:%M:%S')
# 用途：监控Java进程内存使用率，超过阈值时自动重启

# 获取脚本所在目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# 配置文件路径
CONFIG_FILE="${SCRIPT_DIR}/monitor_config.conf"

# 日志文件路径
LOG_DIR="${SCRIPT_DIR}/logs"
LOG_FILE="${LOG_DIR}/process_monitor.log"

# 重启记录文件
RESTART_LOG="${LOG_DIR}/restart_history.log"

# 创建日志目录
mkdir -p "${LOG_DIR}"

# 加载.env文件
load_env_file() {
    local env_file="${SCRIPT_DIR}/.env"
    if [ -f "$env_file" ]; then
        log_info "正在加载 .env 文件..."
        set -a # 自动导出所有变量
        # shellcheck source=.env
        source "$env_file"
        set +a # 停止自动导出
    fi
}

# URL编码函数 (兼容Bash)
rawurlencode() {
  local string="${1}"
  local strlen=${#string}
  local encoded=""
  local pos c o

  for (( pos=0 ; pos<strlen ; pos++ )); do
     c=${string:$pos:1}
     case "$c" in
        [-_.~a-zA-Z0-9] ) o="${c}" ;;
        * )               printf -v o '%%%02x' "'$c"
     esac
     encoded+="${o}"
  done
  echo "${encoded}"
}

# 发送钉钉通知
send_dingtalk_notification() {
    # 检查webhook url是否配置
    if [[ -z "${dingtalk_webhook_url}" ]]; then
        log_debug "钉钉 Webhook URL 未配置，跳过发送通知。"
        return
    fi

    # 检查secret是否配置
    if [[ -z "${dingtalk_secret}" ]]; then
        log_warn "检测到钉钉 Webhook URL，但未配置 Secret，跳过发送通知。"
        return
    fi

    local message="$1"
    local timestamp
    timestamp=$(date +%s%3N)
    local sign_content="${timestamp}\n${dingtalk_secret}"
    local sign
    sign=$(echo -n -e "${sign_content}" | openssl dgst -sha256 -hmac "${dingtalk_secret}" -binary | base64)
    local sign_url_encoded
    sign_url_encoded=$(rawurlencode "$sign")

    local signed_url="${dingtalk_webhook_url}&timestamp=${timestamp}&sign=${sign_url_encoded}"

    local json_payload
    json_payload=$(printf '{"msgtype":"markdown","markdown":{"title":"进程监控通知","text":"%s"},"at":{"isAtAll":false}}' "$message")

    log_info "正在发送钉钉通知..."
    # 使用curl发送，增加超时和重试机制
    local response
    response=$(curl -s -w "\n%{http_code}" --connect-timeout 5 --max-time 10 -X POST "${signed_url}" \
         -H "Content-Type: application/json" \
         -d "${json_payload}")

    local http_code
    http_code=$(echo "$response" | tail -n1)
    local body
    body=$(echo "$response" | sed '$d')

    if [[ "$http_code" -eq 200 ]] && [[ $(echo "$body" | grep -c '"errcode":0') -gt 0 ]]; then
        log_info "钉钉通知发送成功。"
    else
        log_error "钉钉通知发送失败。响应码: ${http_code}, 响应内容: ${body}"
    fi
}

# 日志函数
log_message() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}

# 错误处理函数
log_error() {
    log_message "ERROR" "$1"
}

# 信息日志函数
log_info() {
    log_message "INFO" "$1"
}

# 警告日志函数
log_warn() {
    log_message "WARN" "$1"
}

# 调试日志函数
log_debug() {
    log_message "DEBUG" "$1"
}

# 检查配置文件是否存在
check_config_file() {
    if [[ ! -f "$CONFIG_FILE" ]]; then
        log_error "配置文件不存在: $CONFIG_FILE"
        return 1
    fi
    return 0
}

# 获取进程内存使用率
get_process_memory() {
    local process_name="$1"
    
    # 使用ps命令获取进程信息，匹配进程名，只取第一行
    # 使用更精确的匹配，避免匹配到其他相关进程
    local ps_output=$(ps aux | grep -v grep | grep -w "$process_name" | head -1)
    
    if [[ -z "$ps_output" ]]; then
        echo "0"
        return 1
    fi
    
    # 提取内存使用率（第4列）
    local memory_percent=$(echo "$ps_output" | awk '{print $4}')
    
    # 清理数据：移除所有非数字和小数点的字符
    local cleaned_memory=$(echo "$memory_percent" | tr -cd '0-9.')
    
    # 提取整数部分
    local memory_int
    if [[ "$cleaned_memory" == *.* ]]; then
        memory_int=$(echo "$cleaned_memory" | cut -d. -f1)
    else
        memory_int="$cleaned_memory"
    fi
    
    # 验证结果是否为有效的数字
    if [[ "$memory_int" =~ ^[0-9]+$ ]] && [[ "$memory_int" -ge 0 ]] && [[ "$memory_int" -le 100 ]]; then
        echo "$memory_int"
        return 0
    else
        log_error "提取的内存数据无效: 原始=$memory_percent, 清理后=$cleaned_memory, 整数=$memory_int"
        echo "0"
        return 1
    fi
}

# 获取进程CPU使用率（使用top命令获取实时数据）
get_process_cpu() {
    local process_name="$1"
    
    # 获取进程PID
    local pid=$(ps aux | grep -v grep | grep -w "$process_name" | head -1 | awk '{print $2}')
    
    if [[ -z "$pid" ]]; then
        echo "0"
        return 1
    fi
    
    # 验证PID是否为数字
    if ! [[ "$pid" =~ ^[0-9]+$ ]]; then
        log_error "获取的PID无效: $pid"
        echo "0"
        return 1
    fi
    
    # 使用top命令获取实时CPU使用率
    # -b: 批处理模式, -n 1: 只刷新一次, -p: 指定PID
    local top_output=$(top -b -n 1 -p "$pid" 2>/dev/null | tail -n +8)
    
    if [[ -z "$top_output" ]]; then
        log_warn "无法获取进程 $process_name (PID: $pid) 的top信息"
        # 降级使用ps命令
        local ps_output=$(ps aux | grep -v grep | grep -w "$process_name" | head -1)
        if [[ -n "$ps_output" ]]; then
            local cpu_percent=$(echo "$ps_output" | awk '{print $3}')
            local cleaned_cpu=$(echo "$cpu_percent" | tr -cd '0-9.')
            if [[ "$cleaned_cpu" == *.* ]]; then
                cpu_int=$(echo "$cleaned_cpu" | cut -d. -f1)
            else
                cpu_int="$cleaned_cpu"
            fi
            if [[ "$cpu_int" =~ ^[0-9]+$ ]] && [[ "$cpu_int" -ge 0 ]] && [[ "$cpu_int" -le 100 ]]; then
                echo "$cpu_int"
                return 0
            fi
        fi
        echo "0"
        return 1
    fi
    
    # 从top输出中提取CPU使用率（第9列）
    local cpu_percent=$(echo "$top_output" | awk '{print $9}')
    
    # 清理数据：移除所有非数字和小数点的字符
    local cleaned_cpu=$(echo "$cpu_percent" | tr -cd '0-9.')
    
    # 提取整数部分（向上取整）
    local cpu_int
    if [[ "$cleaned_cpu" == *.* ]]; then
        local decimal_part=$(echo "$cleaned_cpu" | cut -d. -f2)
        local integer_part=$(echo "$cleaned_cpu" | cut -d. -f1)
        # 如果小数部分大于0，则整数部分加1（向上取整）
        if [[ -n "$decimal_part" ]] && [[ "$decimal_part" -gt 0 ]]; then
            cpu_int=$((integer_part + 1))
        else
            cpu_int="$integer_part"
        fi
    else
        cpu_int="$cleaned_cpu"
    fi
    
    # 处理多核CPU情况（top可能显示超过100%）
    if [[ "$cpu_int" -gt 100 ]]; then
        # 限制最大值为100，避免后续比较出现问题
        cpu_int=100
    fi
    
    # 验证结果是否为有效的数字
    if [[ "$cpu_int" =~ ^[0-9]+$ ]] && [[ "$cpu_int" -ge 0 ]] && [[ "$cpu_int" -le 100 ]]; then
        echo "$cpu_int"
        return 0
    else
        log_error "提取的CPU数据无效: 原始=$cpu_percent, 清理后=$cleaned_cpu, 整数=$cpu_int"
        echo "0"
        return 1
    fi
}

# 检查进程是否存在
is_process_running() {
    local process_name="$1"
    # 使用与get_process_memory相同的匹配逻辑
    local ps_output=$(ps aux | grep -v grep | grep -w "$process_name")
    
    if [[ -n "$ps_output" ]]; then
        return 0  # 进程存在
    else
        return 1  # 进程不存在
    fi
}

# 获取上次重启时间
get_last_restart_time() {
    local process_name="$1"
    local last_restart_file="${LOG_DIR}/.last_restart_${process_name}"
    
    if [[ -f "$last_restart_file" ]]; then
        cat "$last_restart_file"
    else
        echo "0"
    fi
}

# 记录重启时间
record_restart_time() {
    local process_name="$1"
    local current_time=$(date +%s)
    local last_restart_file="${LOG_DIR}/.last_restart_${process_name}"
    
    echo "$current_time" > "$last_restart_file"
}

# 记录CPU检测状态
record_cpu_detection() {
    local process_name="$1"
    local cpu_usage="$2"
    local threshold="$3"
    
    local detection_file="${LOG_DIR}/.cpu_detection_${process_name}"
    local current_time=$(date +%s)
    
    # 创建或更新检测记录
    if [[ -f "$detection_file" ]]; then
        # 读取现有记录
        local count=$(cat "$detection_file" | cut -d: -f1)
        local last_time=$(cat "$detection_file" | cut -d: -f2)
        local time_diff=$((current_time - last_time))
        
        # 如果超过5分钟，重置计数
        if [[ $time_diff -gt 300 ]]; then
            echo "1:$current_time:$cpu_usage:$threshold" > "$detection_file"
        else
            # 增加计数
            echo "$((count + 1)):$current_time:$cpu_usage:$threshold" > "$detection_file"
        fi
    else
        # 创建新记录
        echo "1:$current_time:$cpu_usage:$threshold" > "$detection_file"
    fi
}

# 获取CPU检测状态
get_cpu_detection_status() {
    local process_name="$1"
    local detection_file="${LOG_DIR}/.cpu_detection_${process_name}"
    
    if [[ -f "$detection_file" ]]; then
        cat "$detection_file"
    else
        echo "0:0:0:0"
    fi
}

# 重置CPU检测状态
reset_cpu_detection() {
    local process_name="$1"
    local detection_file="${LOG_DIR}/.cpu_detection_${process_name}"
    
    if [[ -f "$detection_file" ]]; then
        rm -f "$detection_file"
    fi
}

# 检查是否需要重启（基于连续检测）
should_restart_for_cpu() {
    local process_name="$1"
    local current_cpu="$2"
    local threshold="$3"
    local consecutive_required=3  # 需要连续3次检测超过阈值
    
    # 如果当前CPU未超过阈值，重置状态并返回不需要重启
    if [[ $current_cpu -le $threshold ]]; then
        reset_cpu_detection "$process_name"
        return 1
    fi
    
    # 记录本次检测
    record_cpu_detection "$process_name" "$current_cpu" "$threshold"
    
    # 获取检测状态
    local detection_status=$(get_cpu_detection_status "$process_name")
    local count=$(echo "$detection_status" | cut -d: -f1)
    local last_time=$(echo "$detection_status" | cut -d: -f2)
    local last_cpu=$(echo "$detection_status" | cut -d: -f3)
    
    log_info "进程 $process_name CPU检测状态: 连续${count}次超过阈值, 当前${current_cpu}%, 阈值${threshold}%"
    
    # 检查是否达到连续检测要求
    if [[ $count -ge $consecutive_required ]]; then
        log_warn "进程 $process_name 连续${count}次CPU超过阈值，准备重启"
        return 0
    else
        log_info "进程 $process_name CPU超过阈值但未达到连续检测要求(${count}/${consecutive_required})"
        return 1
    fi
}

# 检查是否可以重启（避免频繁重启）
can_restart() {
    local process_name="$1"
    local min_interval_minutes="$2"
    
    local last_restart=$(get_last_restart_time "$process_name")
    local current_time=$(date +%s)
    local min_interval_seconds=$((min_interval_minutes * 60))
    
    local time_diff=$((current_time - last_restart))
    
    if [[ $time_diff -ge $min_interval_seconds ]]; then
        return 0  # 可以重启
    else
        local remaining_time=$(((min_interval_seconds - time_diff) / 60))
        log_warn "进程 $process_name 距离上次重启不足 $min_interval_minutes 分钟，还需等待 $remaining_time 分钟"
        return 1  # 不能重启
    fi
}

# 杀死进程
kill_process() {
    local process_name="$1"
    
    log_info "正在停止进程: $process_name"
    
    # 获取进程PID，使用与其他函数一致的匹配逻辑
    local pids=$(ps aux | grep -v grep | grep -w "$process_name" | awk '{print $2}')
    
    if [[ -n "$pids" ]]; then
        for pid in $pids; do
            log_info "正在杀死进程 PID: $pid"
            kill -9 "$pid"
            
            # 等待进程真正停止
            local count=0
            while kill -0 "$pid" 2>/dev/null && [[ $count -lt 30 ]]; do
                sleep 1
                ((count++))
            done
            
            if kill -0 "$pid" 2>/dev/null; then
                log_error "无法停止进程 PID: $pid"
                return 1
            else
                log_info "成功停止进程 PID: $pid"
            fi
        done
    else
        log_warn "未找到进程: $process_name"
    fi
    
    return 0
}

# 启动进程
start_process() {
    local startup_script="$1"
    local work_dir="$2"
    local process_name="$3"
    
    log_info "正在启动进程: $process_name"
    log_info "工作目录: $work_dir"
    log_info "启动脚本: $startup_script"
    
    # 检查启动脚本是否存在
    if [[ ! -f "$startup_script" ]]; then
        log_error "启动脚本不存在: $startup_script"
        return 1
    fi
    
    # 检查工作目录是否存在
    if [[ ! -d "$work_dir" ]]; then
        log_error "工作目录不存在: $work_dir"
        return 1
    fi
    
    # 切换到工作目录并执行启动脚本
    cd "$work_dir" || {
        log_error "无法切换到工作目录: $work_dir"
        return 1
    }
    
    # 给启动脚本执行权限
    chmod +x "$startup_script"
    
    # 执行启动脚本
    bash "$startup_script" > /dev/null 2>&1
    
    if [[ $? -eq 0 ]]; then
        log_info "启动脚本执行成功"
        
        # 等待进程启动
        sleep 10
        
        # 验证进程是否启动成功
        if is_process_running "$process_name"; then
            log_info "进程 $process_name 启动成功"
            return 0
        else
            log_error "进程 $process_name 启动失败"
            return 1
        fi
    else
        log_error "启动脚本执行失败"
        return 1
    fi
}

# 重启进程
restart_process() {
    local process_name="$1"
    local startup_script="$2"
    local work_dir="$3"
    local min_interval="$4"
    
    # 检查是否可以重启
    if ! can_restart "$process_name" "$min_interval"; then
        return 1
    fi
    
    log_info "========== 开始重启进程: $process_name =========="
    
    # 记录重启到历史日志
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 重启进程: $process_name (内存占用过高)" >> "$RESTART_LOG"
    
    # 停止进程
    if kill_process "$process_name"; then
        # 等待一段时间确保进程完全停止
        sleep 5
        
        # 启动进程
        if start_process "$startup_script" "$work_dir" "$process_name"; then
            # 记录重启时间
            record_restart_time "$process_name"
            # 重置CPU检测状态
            reset_cpu_detection "$process_name"
            log_info "========== 进程 $process_name 重启成功 =========="
            return 0
        else
            log_error "========== 进程 $process_name 重启失败 =========="
            return 1
        fi
    else
        log_error "========== 无法停止进程 $process_name，重启失败 =========="
        return 1
    fi
}

# 监控单个进程
monitor_single_process() {
    local process_name="$1"
    local memory_threshold="$2"
    local cpu_threshold="$3"
    local startup_script="$4"
    local work_dir="$5"
    local min_interval="$6"
    
    log_info "开始监控进程: $process_name (内存阈值: ${memory_threshold}%, CPU阈值: ${cpu_threshold}%)"
    log_debug "监控参数: 进程名='$process_name', 内存阈值='$memory_threshold', CPU阈值='$cpu_threshold', 启动脚本='$startup_script', 工作目录='$work_dir', 重启间隔='$min_interval'"
    
    # 检查进程是否运行
    if ! is_process_running "$process_name"; then
        log_warn "进程 $process_name 未运行，尝试启动..."
        start_process "$startup_script" "$work_dir" "$process_name"
        return
    fi
    
    local current_memory=0
    if [[ "$memory_threshold" -gt 0 ]]; then
        current_memory=$(get_process_memory "$process_name")
        if [[ $? -ne 0 ]]; then
            log_warn "无法获取进程 $process_name 的内存使用率，跳过此次内存检查。"
            current_memory=0 # 重置为0，避免影响判断
        else
            log_info "进程 $process_name 当前内存使用率: ${current_memory}%"
        fi
    fi

    local current_cpu=0
    if [[ "$cpu_threshold" -gt 0 ]]; then
        current_cpu=$(get_process_cpu "$process_name")
        if [[ $? -ne 0 ]]; then
            log_warn "无法获取进程 $process_name 的CPU使用率，跳过此次CPU检查。"
            current_cpu=0 # 重置为0，避免影响判断
        else
            log_info "进程 $process_name 当前CPU使用率: ${current_cpu}%"
        fi
    fi

    # 检查是否有任一指标超过阈值
    local reason=""
    local restart_needed=false

    if [[ "$memory_threshold" -gt 0 ]] && [[ "$current_memory" -gt "$memory_threshold" ]]; then
        reason="内存使用率 (${current_memory}%) 超过阈值 (${memory_threshold}%)"
        restart_needed=true
    fi

    if [[ "$cpu_threshold" -gt 0 ]] && [[ "$current_cpu" -gt "$cpu_threshold" ]]; then
        # 使用新的连续检测逻辑判断CPU是否需要重启
        if should_restart_for_cpu "$process_name" "$current_cpu" "$cpu_threshold"; then
            if $restart_needed; then
                reason+=", 且CPU使用率 (${current_cpu}%) 连续超过阈值 (${cpu_threshold}%)"
            else
                reason="CPU使用率 (${current_cpu}%) 连续超过阈值 (${cpu_threshold}%)"
            fi
            restart_needed=true
        else
            # CPU超过阈值但未达到连续检测要求，不触发重启
            log_info "进程 $process_name CPU瞬时超过阈值，但未达到重启条件"
        fi
    else
        # CPU正常，重置检测状态
        reset_cpu_detection "$process_name"
    fi

    # 如果需要重启，则执行操作
    if $restart_needed; then
        log_warn "进程 $process_name 因 ${reason}，准备重启"
        
        # 发送钉钉通知
        local dingtalk_message="**[监控告警] 进程将自动重启**\n\n- **主机名**: $(hostname)\n- **进程名**: ${process_name}\n- **触发原因**: ${reason}\n- **时间**: $(date '+%Y-%m-%d %H:%M:%S')\n\n> 系统将立即尝试重启该进程以恢复服务。"
        send_dingtalk_notification "$dingtalk_message"

        restart_process "$process_name" "$startup_script" "$work_dir" "$min_interval"
    else
        log_info "进程 $process_name各项指标正常"
    fi
}

# 主监控函数
main_monitor() {
    log_info "========== 开始进程监控 =========="
    
    # 检查配置文件
    if ! check_config_file; then
        exit 1
    fi
    
    # 读取配置文件并监控每个进程
    while IFS=':' read -r process_name memory_threshold cpu_threshold startup_script work_dir min_interval; do
        # 跳过注释行和空行
        if [[ $process_name =~ ^#.*$ ]] || [[ -z "$process_name" ]] || [[ "$process_name" =~ ^[[:space:]]*$ ]]; then
            continue
        fi
        
        # 去除前后空格和换行符
        process_name=$(echo "$process_name" | xargs | tr -d '\r\n')
        memory_threshold=$(echo "${memory_threshold:-0}" | xargs | tr -d '\r\n')
        cpu_threshold=$(echo "${cpu_threshold:-0}" | xargs | tr -d '\r\n')
        startup_script=$(echo "$startup_script" | xargs | tr -d '\r\n')
        work_dir=$(echo "$work_dir" | xargs | tr -d '\r\n')
        min_interval=$(echo "$min_interval" | xargs | tr -d '\r\n')
        
        # 为空时设置默认值0
        memory_threshold=${memory_threshold:-0}
        cpu_threshold=${cpu_threshold:-0}
        
        # 验证配置参数
        if [[ -z "$process_name" ]] || [[ -z "$startup_script" ]] || [[ -z "$work_dir" ]] || [[ -z "$min_interval" ]]; then
            log_error "配置行核心参数不足，跳过: $process_name:$memory_threshold:$cpu_threshold:$startup_script:$work_dir:$min_interval"
            continue
        fi
        
        # 验证内存阈值是有效数字
        if ! [[ "$memory_threshold" =~ ^[0-9]+$ ]] || [[ "$memory_threshold" -lt 0 ]] || [[ "$memory_threshold" -gt 100 ]]; then
            log_error "内存阈值无效，必须是0-100之间的整数 (0为禁用)，当前值: '$memory_threshold'，跳过此配置"
            continue
        fi

        # 验证CPU阈值是有效数字
        if ! [[ "$cpu_threshold" =~ ^[0-9]+$ ]] || [[ "$cpu_threshold" -lt 0 ]] || [[ "$cpu_threshold" -gt 100 ]]; then
            log_error "CPU阈值无效，必须是0-100之间的整数 (0为禁用)，当前值: '$cpu_threshold'，跳过此配置"
            continue
        fi

        # 如果内存和CPU阈值都为0，则没有意义，跳过
        if [[ "$memory_threshold" -eq 0 ]] && [[ "$cpu_threshold" -eq 0 ]]; then
            log_warn "进程 $process_name 的内存和CPU监控均未配置，跳过。"
            continue
        fi
        
        # 验证最小重启间隔是有效数字
        if ! [[ "$min_interval" =~ ^[0-9]+$ ]] || [[ "$min_interval" -lt 1 ]]; then
            log_error "最小重启间隔无效，必须是正整数（分钟），当前值: '$min_interval'，跳过此配置"
            continue
        fi
        
        # 监控单个进程
        monitor_single_process "$process_name" "$memory_threshold" "$cpu_threshold" "$startup_script" "$work_dir" "$min_interval"
        
    done < "$CONFIG_FILE"
    
    log_info "========== 进程监控完成 =========="
}

# 显示使用帮助
show_help() {
    echo "Java进程内存及CPU监控脚本使用说明："
    echo ""
    echo "用法: $0 [选项]"
    echo ""
    echo "选项："
    echo "  -h, --help     显示此帮助信息"
    echo "  -c, --config   指定配置文件路径（默认: ./monitor_config.conf）"
    echo "  -l, --log      指定日志目录路径（默认: ./logs）"
    echo "  -t, --test     测试模式，只检查不重启"
    echo ""
    echo "配置文件格式："
    echo "  进程名:内存阈值:CPU阈值:启动脚本路径:工作目录:最小重启间隔(分钟)"
    echo "  (内存或CPU阈值设为0或留空则禁用该项检查)"
    echo ""
    echo "示例："
    echo "  my_service:85:0:/path/start.sh:/path/work:5  # 只监控内存"
    echo "  my_service:0:90:/path/start.sh:/path/work:5  # 只监控CPU"
    echo "  my_service:85:90:/path/start.sh:/path/work:5 # 同时监控内存和CPU"
    echo ""
    echo "  $0                    # 使用默认配置运行"
    echo "  $0 -c /path/config    # 使用指定配置文件"
    echo "  $0 -t                 # 测试模式运行"
    echo ""
    echo "建议添加到crontab中每分钟执行一次："
    echo "  */1 * * * * /path/to/process_monitor.sh"
}

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            show_help
            exit 0
            ;;
        -c|--config)
            CONFIG_FILE="$2"
            shift 2
            ;;
        -l|--log)
            LOG_DIR="$2"
            LOG_FILE="${LOG_DIR}/process_monitor.log"
            RESTART_LOG="${LOG_DIR}/restart_history.log"
            shift 2
            ;;
        -t|--test)
            log_info "测试模式：只检查不重启"
            # 可以添加测试模式的特殊逻辑
            shift
            ;;
        *)
            echo "未知选项: $1"
            show_help
            exit 1
            ;;
    esac
done

# 在主逻辑开始前加载.env文件
load_env_file

# 执行主监控函数
main_monitor 
